home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / snip0493.zip / CHMOD.C < prev    next >
C/C++ Source or Header  |  1993-04-05  |  6KB  |  197 lines

  1. /*
  2. **  CHMOD.C - Retrieve or change a DOS file's attributes
  3. **
  4. **  public domain demo by Bob Stout
  5. **
  6. **  Notes: To expand command line arguments with wildcards,
  7. **         TC/TC++/BC++  - Link in WILDARGS.OBJ.
  8. **         MSC/QC        - Link in SETARGV.OBJ.
  9. **         ZTC/C++       - Link in _MAINx.OBJ, where 'x' is the memory model.
  10. **
  11. **         Allows file list(s) using standard "@file_list_name" convention.
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <dos.h>
  17. #include <ctype.h>
  18. #include <string.h>
  19.  
  20. #define LAST_CHAR(s) (s)[strlen(s)-1]
  21.  
  22. #if defined(__TURBOC__)
  23.  #include <io.h>
  24. #else
  25.  #include <stdarg.h>
  26.  
  27.  #define BOOL(x) (!(!(x)))
  28.  
  29.  int _chmod(const char *path, int func, ...)
  30.  {
  31.        union REGS regs;       /* Use small model so DS will be set      */
  32.        int atr = 0;
  33.        va_list args;
  34.  
  35.        if (0 != (func = BOOL(func)))
  36.        {
  37.             va_start(args, func);
  38.             atr = va_arg(args, int);
  39.        }
  40.        regs.x.ax = 0x4300 + func;
  41.        regs.x.dx = (unsigned)path;
  42.        regs.x.cx = atr;
  43.        intdos(®s, ®s);
  44.        if (regs.x.cflag)
  45.             return -1;
  46.        if (func)
  47.             return atr;
  48.        else return regs.x.cx;
  49.  }
  50.  
  51.  #if !defined(__ZTC__)        /* MSC, etc.                              */
  52.   #define FA_RDONLY _A_RDONLY
  53.   #define FA_HIDDEN _A_HIDDEN
  54.   #define FA_SYSTEM _A_SYSTEM
  55.   #define FA_ARCH   _A_ARCH
  56.   #define FA_LABEL  _A_VOLID
  57.   #define FA_DIREC  _A_SUBDIR
  58.  #endif
  59. #endif
  60.  
  61. int attrib,                   /* Set up new attributes here             */
  62.     atr_setmask = 0,
  63.     atr_clrmask = -1,
  64.     flag = 0;                 /* Passed as func to _chmod()             */
  65.  
  66. void usage(void)              /* Tell 'em they messed up                */
  67. {
  68.       puts("Usage: CHMOD file [file [...file] [+switches] [-switches]");
  69.       puts("Where switches are one or more of:");
  70.       puts("    A: Archive");
  71.       puts("    R: Read only");
  72.       puts("    H: Hidden");
  73.       puts("    S: System");
  74.       puts("File lists may be specified with \"@file_list_name\"");
  75.       puts("With no switches, diplays current attributes.");
  76.       puts("Displayed attributes are as above plus:");
  77.       puts("    D: Subdirectory");
  78.       puts("    V: Volume label");
  79.       exit(1);
  80. }
  81.  
  82. void setattr(char atr)        /* Set bits in attribute                  */
  83. {
  84.       switch (toupper(atr))
  85.       {
  86.       case 'A':
  87.             atr_setmask |= FA_ARCH;
  88.             break;
  89.       case 'R':
  90.             atr_setmask |= FA_RDONLY;
  91.             break;
  92.       case 'S':
  93.             atr_setmask |= FA_SYSTEM;
  94.             break;
  95.       case 'H':
  96.             atr_setmask |= FA_HIDDEN;
  97.             break;
  98.       default:
  99.             usage();
  100.       }
  101. }
  102.  
  103. void clrattr(char atr)        /* Clear bits in attribute                */
  104. {
  105.       switch (toupper(atr))
  106.       {
  107.       case 'A':
  108.             atr_clrmask &= ~FA_ARCH;
  109.             break;
  110.       case 'R':
  111.             atr_clrmask &= ~FA_RDONLY;
  112.             break;
  113.       case 'S':
  114.             atr_clrmask &= ~FA_SYSTEM;
  115.             break;
  116.       case 'H':
  117.             atr_clrmask &= ~FA_HIDDEN;
  118.             break;
  119.       default:
  120.             usage();
  121.       }
  122. }
  123.  
  124. void show_atr(char *path)
  125. {
  126.       char astr[7], *ptr;
  127.  
  128.       if (-1 == (attrib = _chmod(strupr(path), 0)))
  129.       {
  130. ATR_ERR:    printf("\aCHMOD: Error! (file: %s)", path);
  131.             exit(-1);
  132.       }
  133.       attrib |= atr_setmask;
  134.       attrib &= atr_clrmask;
  135.       if (-1 == (attrib = _chmod(path, flag, attrib)))
  136.             goto ATR_ERR;
  137.       ptr = astr;
  138.       *ptr++ = (char)((attrib & FA_ARCH)   ? 'A' : '.');
  139.       *ptr++ = (char)((attrib & FA_RDONLY) ? 'R' : '.');
  140.       *ptr++ = (char)((attrib & FA_SYSTEM) ? 'S' : '.');
  141.       *ptr++ = (char)((attrib & FA_HIDDEN) ? 'H' : '.');
  142.       *ptr++ = (char)((attrib & FA_DIREC)  ? 'D' : '.');
  143.       *ptr++ = (char)((attrib & FA_LABEL)  ? 'V' : '.');
  144.       *ptr = '\0';
  145.       printf("%-15s %s\n", path, astr);
  146. }
  147.  
  148. int main (int argc, char *argv[])
  149. {
  150.       int i, j;
  151.  
  152.       if (2 > argc)
  153.             usage();
  154.       for (i = 1; i < argc; ++i)    /* Build attribute masks            */
  155.       {
  156.             switch (*argv[i])
  157.             {
  158.             case '+':
  159.                   for (j = 1; argv[i][j]; ++j)
  160.                         setattr(argv[i][j]);
  161.                   flag = 1;
  162.                   break;
  163.             case '-':
  164.                   for (j = 1; argv[i][j]; ++j)
  165.                         clrattr(argv[i][j]);
  166.                   flag = 1;
  167.                   break;
  168.             default:
  169.                   break;            /* Assume it's a file name          */
  170.             }
  171.       }
  172.       for (i = 1; i < argc; ++i)    /* Scan filenames                   */
  173.       {
  174.             if (strchr("+-", *argv[i]))
  175.                   continue;
  176.             if ('@' == *argv[i])
  177.             {
  178.                   FILE *fp;
  179.                   char buf[256], *ptr = &argv[i][1];
  180.  
  181.                   if (NULL == (fp = fopen(ptr, "r")))
  182.                   {
  183.                         printf("\aCHMOD: Error opening %s\n", ptr);
  184.                         return -1;
  185.                   }
  186.                   while (NULL != fgets(buf, 255, fp))
  187.                   {
  188.                         LAST_CHAR(buf) = '\0';  /* Strip '\n'           */
  189.                         show_atr(buf);
  190.                   }
  191.                   fclose(fp);
  192.             }
  193.             else  show_atr(argv[i]);
  194.       }
  195.       return 0;
  196. }
  197.